import {t} from 'elysia'
import {ElysiaApp} from '..'
import {DWError, ForbiddenError, isAdmin} from '../utils/auth'
import {isEmpty} from 'lodash'

const addSchema = t.Object({
  pid: t.Number(),
  type: t.Number(),
  icon: t.Optional(t.String()),
  name: t.String(),
  perms: t.String(),
  isShow: t.Optional(t.Number({minimum: 1, maximum: 2})),
  order: t.Number(),
})

const updSchema = t.Intersect([addSchema, t.Object({id: t.Number()})])

export default (app: ElysiaApp) =>
  app
    // 获取全部菜单列表
    .get(
      '/page/list',
      async ({prisma, query}) => {
        const {name, status} = query
        return await prisma.menu.findMany({where: {AND: {name: {contains: name}, isShow: status}}})
      },
      {
        query: t.Object({
          name: t.Optional(t.String()),
          status: t.Optional(t.Numeric({minimum: 1, maximum: 2})),
        }),
      },
    )
    .get(
      '/list',
      async ({prisma}) =>
        await prisma.menu.findMany({
          where: {type: {not: 2}},
          select: {id: true, pid: true, name: true},
        }),
    )
    .get(
      '/api/list',
      async ({prisma}) =>
        await prisma.$queryRaw`
          SELECT
            id, parent_id as pid, name 
          FROM
            sys_menu 
          WHERE
            id IN ( SELECT parent_id FROM sys_menu  WHERE type = 2 ) UNION
          SELECT
            id, parent_id as pid, name
          FROM
            sys_menu
          WHERE
            type = 2;`,
    )
    .post(
      '/add',
      async ({prisma, body}) => {
        const {pid, type, icon, name, perms, isShow, order} = body
        const _menu = await prisma.menu.findFirst({where: {perms}})
        if (_menu) throw new ForbiddenError('此权限标识已存在，请勿重新添加')
        if (type !== 2) {
          if (isEmpty(icon)) throw new DWError('Unprocessable Content', 'icon is required')
          if (!isShow) throw new DWError('Unprocessable Content', 'isShow is required')
        }
        const data = await prisma.menu.create({
          data: {pid, type, icon, name, perms, isShow, order},
        })
        const role = await prisma.role.findFirst({where: {name: 'admin'}})
        await prisma.roleMenu.create({
          data: {roleId: role!.id, menuId: data.id},
        })
        return '菜单新增成功'
      },
      {body: addSchema},
    )
    .patch(
      '/upd',
      async ({body, prisma}) => {
        const {id, pid, type, icon, name, perms, isShow, order} = body
        const _menu = await prisma.menu.findFirst({where: {perms}})
        const _curMenu = await prisma.menu.findFirst({where: {id}})
        if (_menu && _curMenu!.perms !== _menu.perms) throw new ForbiddenError('此权限标识已存在，请勿修改')
        if (type !== 2) {
          if (isEmpty(icon)) throw new DWError('Unprocessable Content', 'icon is required')
          if (!isShow) throw new DWError('Unprocessable Content', 'isShow is required')
        }
        await prisma.menu.update({
          where: {id},
          data: {pid, type, icon, name, perms, isShow, order},
        })
        return '菜单修改成功'
      },
      {body: updSchema},
    )
    .delete(
      '/del',
      async ({body, prisma, store: {curUser}}) => {
        if (!(await isAdmin(prisma, curUser))) throw new ForbiddenError('普通用户不可删除，请联系管理员操作')
        const {id} = body
        const delRoleMenu = prisma.roleMenu.deleteMany({where: {menuId: id}})
        const delMenu = prisma.menu.delete({where: {id}})
        await prisma.$transaction([delRoleMenu, delMenu])
        return '菜单删除成功'
      },
      {body: t.Object({id: t.Numeric()})},
    )
